//
//  ZQueue.h
//  Part of Z-Way.C library
//
//  Created by Alex Skalozub on 1/9/12.
//  Based on Z-Way source code written by Christian Paetz and Poltorak Serguei
//
//  Copyright (c) 2012 Z-Wave.Me
//  All rights reserved
//  info@z-wave.me
//
//  This source file is subject to the terms and conditions of the
//  Z-Wave.Me Software License Agreement which restricts the manner
//  in which it may be used.
//

#ifndef zway_queue_h
#define zway_queue_h


struct _ZQueueEntry
{
    ZJob job;
    ZQueueEntry next;
};

// free all jobs in queue
void _zway_queue_free(ZWay zway);

// remove job from queue
ZWError _zway_queue_remove_job(ZWay zway, const ZJob job);

// remove job from queue (unsafe version)
ZWError _zway_queue_remove_job_unsafe(ZWay zway, const ZJob job);

// add job to queue
ZWError _zway_queue_add_job(ZWay zway, ZJob job);

// add job to queue by pointer
ZWError _zway_queue_add_pjob(ZWay zway, ZJob * pjob);

// add job to queue (unsafe version)
ZWError _zway_queue_add_job_unsafe(ZWay zway, ZJob job);

// returns a job awaiting for ACK, or NULL if there's no one
ZJob _zway_queue_find_awaiting_ack(ZWay zway);

// returns a job awaiting response, or NULL if there's no one
ZJob _zway_queue_find_awaiting_response(ZWay zway, ZWBYTE functionId);

// returns a job awaiting callback, or NULL if there's no one
ZJob _zway_queue_find_awaiting_callback(ZWay zway, ZWBYTE functionId, ZWBYTE callbackId);

// returns a job awaiting any callback, or NULL if there's no one
ZJob _zway_queue_find_awaiting_callback_any(ZWay zway, ZWBYTE functionId);

// detach the job from other jobs encapulating this one
void _zway_queue_detach_encapsulated_jobs(const ZWay zway, ZJob job);

// returns jobs as a job list, optionally filtered
ZJobList _zway_queue_get_jobs(const ZWay zway, const ZJobListFilter filter);

// remove jobs for specific node from queue
void _zway_queue_remove_jobs_for_node(ZWay zway, ZWNODE node_id);

// returns if there's any job for node queued
ZWBOOL _zway_queue_has_jobs_for_node(ZWay zway, ZWNODE node_id);

// match incoming packets agains expected replies
ZWBOOL _zway_queue_match_reply(ZWay zway, ZWNODE node_id, ZWBYTE instance_id, ZWBYTE reply_size, ZWBYTE * reply);

// find first request matching to incoming packets
void _zway_queue_find_matching_request_payload(ZWay zway, ZWNODE node_id, ZWBYTE instance_id, ZWBYTE reply_size, ZWBYTE * reply, ZWBYTE *length, const ZWBYTE ** payload, ZWBYTE *key_class, const char **description);

// returns if there are jobs waiting for replies
ZWBOOL _zway_queue_has_jobs_expecting_reply(ZWay zway, ZWNODE node_id);

// mark job waiting for reply as rejected
void _zway_queue_request_rejected(ZWay zway, ZWNODE node_id);

// delay the request packet a bit more in the queue
void _zway_queue_delay_request(ZWay zway, ZWNODE node_id, ZWBYTE instance_id, ZWBYTE reply_size, ZWBYTE * reply, int delay);

// returns if more packets are waiting for security to same node is this job
ZWBOOL _zway_queue_have_more_secure_packets(ZWay zway, ZJob job);

// returns if two jobs are duplicate (job payload starting from byte startFrom); if startFrom and length are zero, inspect the full payload
ZWBOOL _zway_is_duplicate_job(ZJob existing, ZJob job, ZWBYTE startFrom, ZWBYTE length);

#endif
